#include "Game.h"
#include "FileSystem/CFileSystem.h"
#include "Font.h"
#include "CWriteMemory.h"
#include "CWriteFile.h"
#include "ParticleSystem/ParticleHolder.h"


CGame* gp_GameApp = NULL;
float CGame::m_gamePlayTimeStep = 0;
bool CGame::m_bIsGameplayPaused = false;
#define SAVE_MEMORY_BUFFER_SIZE		(415000)
CGame::CGame(void)
{
	miMilliTime = 0;
	miLastMilliTime = 0;
	miFrameCounter = 0;
	m_saveBuffer = GL_NEW CWriteMemory(SAVE_MEMORY_BUFFER_SIZE);
}
CGame::~CGame(void)
{
	SAFE_DELETE( _gfx );
	SAFE_DELETE( mp_Font);
}

void CGame::SaveData()
{
	//SaveDataToMemory();
	SaveDataToFile();
}
#define SAVE_GAME_SERIAL_NR 2108
void CGame::SaveDataToFile()
{
	CWriteFile* pFile = GL_NEW CWriteFile("zbc.sav",false);
	if (pFile)
	{
		pFile->WriteS32(SAVE_GAME_SERIAL_NR);
		//m_objectManager
		m_objectManager->SaveData(pFile);
		m_itemManager->SaveData(pFile);
		m_cinematic->SaveData(pFile);
	}
	SAFE_DEL(pFile);
}

void CGame::SaveDataToMemory()
{
	m_saveBuffer->seek(0);

	CWriteFile* pFile = (CWriteFile*)m_saveBuffer;
	pFile->WriteS32(SAVE_GAME_SERIAL_NR);
	//m_objectManager
	m_objectManager->SaveData(pFile);
	m_itemManager->SaveData(pFile);
	m_cinematic->SaveData(pFile);
}

void CGame::SaveDataToFileFromMemory()
{
	if (m_saveBuffer->getPos() > 0)
	{
		CWriteFile* pFile = GL_NEW CWriteFile("zbc.sav",false);
		if (pFile)
			pFile->write(m_saveBuffer->GetBuffer(), m_saveBuffer->getPos());
		SAFE_DEL(pFile);
		m_saveBuffer->seek(0);
	}
}


void CGame::LoadData()
{
	LoadDataFromFile();
}
void CGame::LoadDataFromFile()
{
	CReadFile* pFile =  GL_NEW CReadFile("zbc.sav");

	if (pFile)
	{
		if(pFile->ReadS32() == SAVE_GAME_SERIAL_NR)
		{
			m_objectManager->LoadData(pFile);
			m_itemManager->LoadData(pFile);
			m_cinematic->LoadData(pFile);
		}
	}

	SAFE_DEL(pFile);
}
void CGame::LoadDataFromMemory()
{
	
}
void CGame::Initialize()
{

	CMath::SetRandomSeed(0x0f0f0f0f);
	mp_Font = NULL;
	_gfx = GL_NEW cGfx();
	mp_TexMgr = GL_NEW TextureManager();
	_gfx->SetTexMgr( mp_TexMgr );
	mp_TexMgr->Init();

	m_resManager = GL_NEW ResManager();
	m_resManager->initialize();

	m_ScreenManager = GL_NEW ScreenManager();

	FileSystem = irrnew CFileSystem();
	
	PushState(State::GS_Gameplay);
	//PushState(State::GS_LevelEnd);
	m_isLoadDone = false;

	TIME_DEBUG_START_FRAME();
}

void CGame::Release()
{
	
}


eIPLUpdateStatus CGame::Update(unsigned long delta_t_miliseconds)
{
	eIPLUpdateStatus status = IPL_US_APP_ACTIVE;
	
	miMilliTime += delta_t_miliseconds;
#ifdef WIN32
	//if (miMilliTime - miLastMilliTime < 1000.0f/MAX_FPS)
	//{
	//	//SDL_Delay((1000.0f/MAX_FPS + 0.5f)  - delta_t_miliseconds);
	//	if((1000.0f/MAX_FPS + 0.5f)  - delta_t_miliseconds >30)
	//	{
	//		int fdfd=0;
	//	}
	//	return IPL_US_APP_IDLE;
	//}
#endif	

	m_gamePlayTimeStep = (miMilliTime - miLastMilliTime)/1000.0f;//1000.0f/MAX_FPS;//
	if(m_gamePlayTimeStep > 1.0f/MAX_FPS)
		m_gamePlayTimeStep = 1.0f/MAX_FPS;

	moTouchInput.Update();
	miFrameCounter++;

	

	StateMachineUpdate();
	TIME_DEBUG_TIME_CHECK("Update");

	return status;
}

void CGame::Paint()
{

//#ifdef WIN32
//		if (miMilliTime - miLastMilliTime < 1000.0f/MAX_FPS)
//			return ;
//#endif

	glClear(/*GL_COLOR_BUFFER_BIT |*/ GL_DEPTH_BUFFER_BIT);
	IPLGLMatrixStack_MatrixMode(IPL_MSE_MODELVIEW);
	glLoadIdentity();
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	//float32 ratio = RATIO_SCREEN;// float32(SCREEN_WIDTH) / float32(SCREEN_HEIGHT);

	b2Vec2 extents(RATIO_SCREEN * HTALL_BY_METERS, HTALL_BY_METERS);
	//extents *= viewZoom;
	b2Vec2 viewCenter(RATIO_SCREEN * HTALL_BY_METERS,HTALL_BY_METERS * 0.6f);
	b2Vec2 lower = viewCenter - extents;
	b2Vec2 upper = viewCenter + extents;
	glOrtho(lower.x, upper.x, lower.y, upper.y,-500,500);
	//glOrtho(0, SCREEN_WIDTH, 0, SCREEN_HEIGHT, -250.0f, 250.0f);
	getGfx()->SetColor(0xffffffff);
	getGfx()->SetTexColor(0xffffffff);

	

	StateMachineDraw2D();
	TIME_DEBUG_TIME_CHECK("Paint");
	TIME_DEBUG_SHOW_LOG();
	TIME_DEBUG_START_FRAME();
	if(mp_Font)
	{
		char buff[32];
		getGfx()->SetColor(0x7fffffff);
		sprintf(buff,"FPS:%d",1000/ (miMilliTime - miLastMilliTime));
		mp_Font->SetTexColor(RGBA(0xff,0x0,0x0,0xff),0xff222222);
		mp_Font->DrawText2((GL_TCHAR*)buff,1,2);
	}

	miLastMilliTime = miMilliTime;

}

void CGame::PauseGame()
{
	
}

void CGame::ResumeGame()
{
	
}

void CGame::ExitGame()
{
	
}


void CGame::DispatchState(int depth, int mode)
{
	switch(GetStateAtDepth(depth))
	{
		case State::GS_Gameplay :			State_Gameplay(depth, mode); break;
		case State::GS_Loading :			State_Loading(depth, mode); break;	
		case State::GS_LevelEnd :			State_LevelEnd(depth, mode); break;}

}

b2Vec2 ConvertScreenToWorld(int32 x, int32 y)
{
	float32 u = x / float32(SCREEN_WIDTH);
	float32 v = (SCREEN_HEIGHT - y) / float32(SCREEN_HEIGHT);

	//float32 ratio = float32(SCREEN_WIDTH) / float32(SCREEN_HEIGHT);
	b2Vec2 extents(RATIO_SCREEN * HTALL_BY_METERS, HTALL_BY_METERS);
	//extents *= viewZoom;
	b2Vec2 viewCenter(RATIO_SCREEN * HTALL_BY_METERS,HTALL_BY_METERS * 0.6f);
	b2Vec2 lower = viewCenter - extents;
	b2Vec2 upper = viewCenter + extents;

	b2Vec2 p;
	p.x = (1.0f - u) * lower.x + u * upper.x;
	p.y = (1.0f - v) * lower.y + v * upper.y;
	return p;
}

IFpsParticleSystemSceneNode* CGame::CloneObjectEffectType(ParticleHolder* parHolder, stringw effectType)
{
	int type = 0;
	bool bFound = false;

	for (int i=0; i < m_EffectsPresets.size(); i++)
	{
		if (m_EffectsPresets[i]->m_effectName == effectType)
		{
			type = i;
			bFound = true;
			break;
		}
	}
	
	if(!bFound)
		return NULL;

	for (u32 i = 0; i < m_EffectsPresets[type]->m_ParticleSystems.size(); i++)
	{
		IFpsParticleSystemSceneNode* pNode = m_EffectsPresets[type]->m_ParticleSystems[i]->clone();
		parHolder->AddChild(pNode);
	}
}